defmodule Vad.AudioChunk do
  @moduledoc false

  use Protobuf, protoc_gen_elixir_version: "0.13.0", syntax: :proto3

  field :audio_data, 1, type: :bytes, json_name: "audioData"
  field :session_id, 2, type: :string, json_name: "sessionId"
end

defmodule Vad.SpeechTimestamps do
  @moduledoc false

  use Protobuf, protoc_gen_elixir_version: "0.13.0", syntax: :proto3

  field :timestamps, 1, repeated: true, type: Vad.Timestamp

  def handle_grpc_message(frame) do
    with {:ok, message_data} <- decode_frame(frame),
         {:ok, parsed_data} <- parse_protobuf(message_data) do
      {:ok, parsed_data}
    else
      {:error, reason} -> {:error, reason}
    end
  end

  defp decode_frame(frame) do
    case frame do
      <<compressed_flag::size(8), _message_length::size(32)-big, message_data::binary>> ->
        if compressed_flag == 0 do
          {:ok, message_data}
        else
          {:error, "Compressed messages are not supported"}
        end

      _ ->
        {:error, "Invalid gRPC frame"}
    end
  end

  defp parse_protobuf(message_data) do
    try do
      {:ok, decode(message_data)}
    rescue
      e in Protobuf.DecodeError -> {:error, "Failed to decode Protobuf data: #{e.message}"}
    end
  end

end

defmodule Vad.Timestamp do
  @moduledoc false

  use Protobuf, protoc_gen_elixir_version: "0.13.0", syntax: :proto3

  field :start, 1, type: :float
  field :end, 2, type: :float


end

defmodule Vad.VADService.Service do
  @moduledoc false

  use GRPC.Service, name: "vad.VADService", protoc_gen_elixir_version: "0.13.0"

  rpc :StreamVAD, stream(Vad.AudioChunk), stream(Vad.SpeechTimestamps)
end

defmodule Vad.VADService.Stub do
  @moduledoc false

  use GRPC.Stub, service: Vad.VADService.Service
end
